/**
 * 
 *
 * \file CoordinateDriveServer.i
 * \brief Python wrap for MaCI - CoordinateDrive Server interface
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 * \author Tapio Taipalus <tapio.taipalus@tkk.fi>
 */

%module CoordinateDriveServer

%include std_string.i
%include std_list.i
//%include std_map.i
%include "typemaps.i"
//%include std_vector.i

%{
#include "MaCI.hpp"
#include "CoordinateDriveData.hpp"
#include "CoordinateDriveTypes.hpp"
#include "CoordinateDriveServer.hpp"
#include "thread.hpp"
#include "sync.hpp"
#include <list>
%}

%include "CoordinateDriveTypes.i"
%include "CoordinateDriveData.i"
%include "../MaCIError.i"
%include "../MaCI.i"
%include "../MaCICtrl/MaCICtrlServer.i"
%include "../common/timestamp.i"

// Forward declare gimi::GIMI
namespace gimi {
  class GIMI;
  class GIMIMessage;
}


namespace MaCI{
  namespace CoordinateDrive{
   
    /** MaCI - CoordinateDrive Server interface
     * 
     * This class contains the methods and types for providing
     * the CoordinateDrive service in the GIMnet.
     */
    class CCoordinateDriveServer : public MaCI::CMaCI,
				   private gim::CThread,
				   private gim::CSync
    {
    public:
      /** Constructor.
       * 
       * Constructor of the CoordinateDriveServer. This requires;
       * a pointer to Initialized and connected GIMI, minor
       * number of this interface (Used as GIMI minor number)
       *
       * @param[in] aMaCICtrlServerPtr Pointer to MaCICtrlServer.
       * @param[in] aInterfaceMinor Interface minor number. Usually
       * used to indicate the instance of devices of same type.
       */
      CCoordinateDriveServer(MaCICtrl::CMaCICtrlServer *aMaCICtrlServerPtr, const int aInterfaceMinor);

      /** Destructor.
       */
      ~CCoordinateDriveServer();

      /** Opens CoordinateDriveServer Server
       *
       * Opens the CoordinateDrive Server,  basicly registers device to GIMI.
       *  
       * @return                Returns a value of type EMaCIError. 
       *                        
       * \see EMaCIError
       */
      MaCI::EMaCIError DoOpen(void);

      /** Close device.
       *
       * Closes the CoordinateDrive. Closes all GIMI registrations and queues.
       *
       * @return                Returns a value of type EMaCIError.
       *
       * \see EMaCIError
       */
      MaCI::EMaCIError DoClose(void);

      /** Wait for a Command.
       *
       * This function waits until new command arrives or timeout occurs.
       * If there is unhandled commands since last read, the next
       * in queue is returned. If you want to clear the queue between calls,
       * use ClearCommandBuffer() function.
       *
       * When a command is succesfully returned, the user can inspect
       * the current command through the GetCommand() call of
       * class CIOData. Then, according to command and its
       * specification, additional datafields may be present, they
       * can be queried by similar Get... functions. See the 
       * description of the data encoder/decoder module CIOData.
       *
       * 
       * \see ClearCommandBuffer()
       * \see CIOData
       * \see MaCI::EMaCIError
       * 
       * @param[out] aData      Reference to CoordinateDriveData. This will
       *                        be filled with incoming command when
       *                        this call is completed succesfully.
       * @param[out] aInfo      Reference to replyInfo. Use this replyInfo 
       *                        to SendReply-function when you have to send 
       *                        a Reply.
       * @param[in] aTimeout_ms Timeout to wait until operation fails
       *                        for timeout.
       * @param[in] aSkipQueued If this value is set to 'true', the
       *                        function will only return the last
       *                        received command and pop older ones
       *                        out from the queue. If this is set to
       *                        'false', all commands are received in
       *                        order. If parameter is undefined, 
       *                        default is 'false'.
       * @return                'KMaCIOK'  when succesfully received
       *                        a new command. KMaCITimeout when operation
       *                        timed out before a command was received.
       *                        Other errors returned when appropriate.
       *                        (See the MaCI::EMaCIError for description)
       * \see EMaCIError
       */
      MaCI::EMaCIError WaitCommand(MaCI::CoordinateDrive::CCoordinateDriveData &OUT,
				   MaCI::CoordinateDrive::TReplyInfo &OUT,
				   const unsigned int aTimeout_ms,
				   bool aSkipQueued = false);

      /**
       * Sends an event which contains a TCoordinate2D- structure in a CCoordinateDriveData.
       * It is used for telling the client that coordinateDrive have reached a point
       *
       * @param[in] aCoord      CCoordinateDriveData which contains a TCoordinate2D-structure
       *
       * @return                true if event sending success
       */
      bool SendArrivedToTargetEvent(MaCI::CoordinateDrive::CCoordinateDriveData &aCoord);

      /** Sends reply message to client
       *
       * @param[in] aData       Reference to CCoordinateDriveData. This data will be sent to
       *                        client for reply
       * @param[in] aInfo       Reference to replyInfo. Get this replyinfo from
       *                        WaitCommand.
       * @return                'KMaCIOK' when reply message succesfully sent.
       *                        Other errors returned when appropriate.
       *                        (See the MaCI::EMaCIError for description)
       * \see EMaCIError
       */
      MaCI::EMaCIError SendReply(MaCI::CoordinateDrive::CCoordinateDriveData &aData,
				 MaCI::CoordinateDrive::TReplyInfo &aInfo);

      /**
       * Sends an event which contains TCoordinate2D- structures in a CCoordinateDriveData.
       * It is used for telling the client all the coordinates set to server side.
       *
       * @param[in] aCoord      CCoordinateDriveData which contains one TCoordinateHeader and 
       *                        TCoordinate2D-structure(s)
       *
       * @return                true if event sending success
       */
      bool SendCoordinatesEvent(MaCI::CoordinateDrive::CCoordinateDriveData &aData);
	  
      /** Clear the incoming commands buffer.
       *
       * This functions clears the accumulated command buffer. This
       * function call may be required if the server for some (weird?)
       * reason wants to skip unprocessed commands. Per default the incoming
       * 'Set' commands are all queued until processed. (This ensures
       * that critical commands don't get lost)
       */
      void ClearCommandBuffer(void);
/**
       * 
       * Notifies the server that it's impossible to drive to wanted coordinate(s).
       *
       * @param[in] aArrayTCoordinate2D    coordinate where the robot is not capable to drive
       *
       */
      bool UnableToDriveToCoordinate(MaCI::CoordinateDrive::TCoordinate2D &aCoordinate2D);

      /**
       * Send an event to inform the client that the server is calculating 
       * the path
       *
       */
      bool SendCalculatingEvent();


      /**
       * Send an event to inform the client that the path is ready
       *
       */
      bool SendPathReadyEvent();
    };


  }

}


